package com.ryder.petmatediarybackend.common.response;

import lombok.Data;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
 * 描述: 分页查询结果封装实体
 *
 * @author Ryder
 * @version 1.0
 * @since 1.0
 * 更新日期: 2025/10/25
 */
@Data
public class PageResult<T> implements Serializable {

    /**
     * 当前页码，默认从1开始计数
     */
    private Integer pageNo = 1;

    /**
     * 每页记录数，默认20条
     */
    private Integer pageSize = 20;

    /**
     * 总记录数（所有符合条件的记录总数，非当前页数量）
     */
    private Integer total = 0;

    /**
     * 总页数，根据总记录数和每页大小自动计算
     */
    private Integer totalPages = 0;

    /**
     * 当前页的数据列表，无数据时返回空列表
     */
    private List<T> result = Collections.emptyList();

    /**
     * 当前页第一条记录的序号（基于1开始计数）
     */
    private Integer start = 1;

    /**
     * 当前页最后一条记录的序号（需结合总记录数动态计算，当前代码未完全实现）
     */
    private Integer end = 0;

    /**
     * 设置当前页的数据列表
     *
     * <p>强制将总记录数（total）设置为当前列表大小 </p>
     *
     * @param result 当前页数据列表，可为空
     */
    public void setRecords(List<T> result) {
        this.result = result;
        if (result != null && !result.isEmpty()) {
            setTotal(result.size());
        }
    }

    /**
     * 设置总记录数并计算分页元数据
     *
     * <p>自动计算总页数（totalPages）和当前页起始序号（start）。</p>
     *
     * @param total 总记录数（必须 >= 0）
     */
    public void setTotal(Integer total) {
        this.total = total;
        if (this.pageSize > 0) {
            this.totalPages = (total / this.pageSize) + (total % this.pageSize == 0 ? 0 : 1);
        } else {
            this.totalPages = 0;
        }
        this.start = (this.pageSize > 0 ? (this.pageNo - 1) * this.pageSize : 0) + 1;
        this.end = (this.start - 1 + this.pageSize * (this.pageNo > 0 ? 1 : 0));
    }

    /**
     * 设置每页记录数
     *
     * <p>此方法用于设置分页查询中每页显示的记录数。需确保传入的值大于0，否则可能导致分页计算错误。</p>
     *
     * <p><b>注意：</b>修改 pageSize 后，需重新计算总页数（totalPages）和当前页的起始序号（start）。</p>
     *
     * @param pageSize 每页记录数（必须大于0）
     * @throws IllegalArgumentException 如果 pageSize 小于或等于0
     */
    public void setPageSize(Integer pageSize) {
        if (pageSize == null || pageSize <= 0) {
            throw new IllegalArgumentException("每页记录数必须大于0");
        }
        this.pageSize = pageSize;
    }

    /**
     * 设置当前页码
     *
     * <p>此方法用于设置分页查询的当前页码。页码从1开始计数，需确保传入的值大于0。</p>
     *
     * <p><b>注意：</b>修改 pageNo 后，需重新计算当前页的起始序号（start）和结束序号（end）。</p>
     *
     * @param pageNo 当前页码（必须大于0）
     * @throws IllegalArgumentException 如果 pageNo 小于或等于0
     */
    public void setPageNo(Integer pageNo) {
        if (pageNo == null || pageNo <= 0) {
            throw new IllegalArgumentException("当前页码必须大于0");
        }
        this.pageNo = pageNo;
    }
}
